package com.xingdata.jjxc.ar_navi;

import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.google.gson.Gson;
import com.xingdata.jjxc.udp.UdpRxThread;
import com.xingdata.jjxc.udp.UdpTxThread;

import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;

import de.greenrobot.event.EventBus;
import protocol.ProtoFilter;
import tcp.TcpServerSocketThread;

/**lxs-------------
 * 通信管理
 * Created by Administrator on 2016/10/14.
 */

public class ARHudComm {
    public interface DeviceConnetionListener{
        void deviceConnected();
        void deviceDisconnected();
    }
    DeviceConnetionListener deviceConnetionListener;
    InetAddress deviceAddr; // 已经连接的设备地址
    String TAG = "ARHudComm";
    UdpTxThread arUdp;
    UdpTxThread broadcastUdp;// 广播
    String deviceIpAddr = "";
    boolean deviceIsConnected = false; // 设备连接状态
    long heartbeatTick;
    Timer heartbeatCheckTimer;
    UdpRxThread deviceHeartbeat;
    TcpServerSocketThread tcpServerSocketThread;
    TcpServerSocketThread onBoardNaviDataThread;
    UdpRxThread onBoadNaviDataReceiver;

    boolean navi_data_debug_mode = false;// 导航AR 调试模式

    static ARHudComm instance =new ARHudComm();

    private ARHudComm(){}

    public static ARHudComm getInstance(){
        return instance;
    }

    public boolean deviceIsConnected(){
        return deviceIsConnected;
    }

    public InetAddress getDeviceAddr(){
        return deviceAddr;
    }

    public void setDeviceConnetionListener(DeviceConnetionListener listener){
        this.deviceConnetionListener = listener;
    }

    public void enableNaviDebugMode(){
        navi_data_debug_mode = true;
    }

    public void setNavi_data_debug_mode(boolean how){
        navi_data_debug_mode = how;
    }

    public void disableNaviDebugMode(){
        navi_data_debug_mode = false;
    }

    public boolean isNavi_data_debug_mode(){
        return  navi_data_debug_mode;
    }

    public void init(){

        broadcastUdp = new UdpTxThread("255.255.255.255",18000);

        deviceHeartbeat = new UdpRxThread("255.255.255.255",60002);
        deviceHeartbeat.setUdpRxListener(new UdpRxThread.UdpReceivedListener() {
            @Override
            public void onUdpReceived(byte[] data, int len) {
                String jsonStr = new String(data,0,len) ;
                ProtoMsg protoMsg = JSON.parseObject(jsonStr,ProtoMsg.class);
                if(protoMsg.action.equals("device.heartbeat")){// 设备心跳
                    Log.i(TAG,"=========> 收到设备心跳");//每隔5s左右会收到一个设备心跳信息
                    heartbeatTick = System.currentTimeMillis();
                }
            }
        });
        heartbeatCheckTimer = new Timer();
        heartbeatCheckTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                long now = System.currentTimeMillis();
                long delta = now - heartbeatTick;
                if(delta >= 10*1000){// 超过10s没有收到设备心跳，说明设备连接已经断开!
                    //Log.e(TAG,"xxxxxxx 设备连接已经断开 xxxxxxx");
                    deviceIsConnected = false;
                    if(deviceConnetionListener!=null){
                        deviceConnetionListener.deviceDisconnected();
                    }
                    EventBus.getDefault().post(new DeviceConnectionEvent(DeviceConnectionEvent.Disconnected));
                }else{
                    // Log.i(TAG,"======= 设备已连接! =======");
                    deviceIsConnected = true;
                    if(deviceConnetionListener!=null){
                        deviceConnetionListener.deviceConnected();
                    }
                    EventBus.getDefault().post(new DeviceConnectionEvent(DeviceConnectionEvent.Connected));
                }
            }
        },1000,5*1000);

        final Gson gson = new Gson();
        tcpServerSocketThread = new TcpServerSocketThread(50002);
        final ProtoFilter protoFilter = new ProtoFilter();
        protoFilter.setLisenter(new ProtoFilter.OnFilterResultListener() {
            @Override
            public void OnMessageReceive(ByteBuffer bb) {
                // 解析消息
                System.out.println("====> head:" +bb.getShort());
                System.out.println("---- total_len:" +bb.getInt());
                System.out.println("---- msg_type:" +bb.getInt());
                System.out.println("---- msg_id:" +bb.getLong());

                int action_len = bb.getInt();
                System.out.println("---- action_len:" +action_len);
                byte[] str_byte= new byte[action_len];
                bb.get(str_byte, 0, action_len);
                String action_string = new String(str_byte);
                System.out.println("action string:"+new String(str_byte));

                int data_len = bb.getInt();
                System.out.println("---- data_len:" +data_len);
                byte[] data_byte= new byte[data_len];
                bb.get(data_byte, 0, data_len);
                System.out.println("data string:"+new String(data_byte));

                try{ // 由于断包，粘包的问题，这里有时候会报解析异常
                    if(action_string.equals("device.heartbeat")){// 设备心跳
                        // Log.i(TAG,"=========> 收到设备心跳");
                        heartbeatTick = System.currentTimeMillis();
                    }

                    if(action_string.equals("device.settings")){
                    }

                }catch (JSONException ex){
                    Log.e("json error",ex.getMessage());
                }
            }
        });
        tcpServerSocketThread.setReceiveListener(new TcpServerSocketThread.ReceiveListener() {
            @Override
            public void onSocketReceived(TcpServerSocketThread server, byte[] data, int len) {
                protoFilter.onDataFiltering(data,len);
            }
        });

        final ProtoFilter filter = new ProtoFilter();
        filter.setLisenter(new ProtoFilter.OnFilterResultListener() {
            @Override
            public void OnMessageReceive(ByteBuffer byteBuffer) {
                // 解析数据包
                short head = byteBuffer.getShort();
                int total_len = byteBuffer.getInt();
                int msg_type = byteBuffer.getInt();
                System.out.println("----> msg_id:" +byteBuffer.getLong());

                int action_len = byteBuffer.getInt();
                byte[] action_bytes = new byte[action_len];
                byteBuffer.get(action_bytes,0,action_len);
                String actionId = new String(action_bytes);

                int data_len = byteBuffer.getInt();
                byte[] data_bytes = new byte[data_len];
                byteBuffer.get(data_bytes,0,data_len);

                Log.w(TAG,"转发车载导航数据=========> on the board");
                // 通过手机将板载导航的数据转发到 AR
                if(actionId.equals("on_board_navi_route") || actionId.equals("on_board_navi_info")){
                    ARHudComm.getInstance().sendToAR(ByteBuffer.wrap(data_bytes));
                }
            }
        });

        onBoardNaviDataThread = new TcpServerSocketThread(19000);
        onBoardNaviDataThread.setReceiveListener(new TcpServerSocketThread.ReceiveListener() {
            @Override
            public void onSocketReceived(TcpServerSocketThread server, byte[] data, int len) {
                    filter.onDataFiltering(data,len);
            }
        });

        tcpServerSocketThread.setAcceptConnectionListener(new TcpServerSocketThread.AcceptConnectionListener() {
            @Override
            public void onNewClientSocketConnected(InetAddress clientAddr) {
                deviceAddr = clientAddr;
                if(arUdp!=null){arUdp.stop();}
                arUdp = new UdpTxThread(deviceAddr.getHostAddress(),18000);//启动UDP 线程，发送到18000 AR端口
            }
        });
    }

    public void sendToAR(ByteBuffer buffer){
        if(arUdp!=null){
            arUdp.enqueue(buffer);
        }

        if(navi_data_debug_mode){
            if(broadcastUdp!=null){
                broadcastUdp.enqueue(buffer);
            }
        }
    }

    public void sendToHud(ByteBuffer buffer){
        tcpServerSocketThread.equeueToSend(buffer);
    }

    public void destroy(){
        if(arUdp!=null)arUdp.stop();
        tcpServerSocketThread.stop();
    }
	
	public static class HudAction {

        public static  final String  NAV_UPDATE_INFO   = "updateNaviInfo";    //
        public static  final String  NAV_UPDATE_SPEED  = "updateNaviSpeed";    //
        public static  final String  SYS_OTA_UPDATE    = "sys_ota_update";     //ota升级
        public static  final String  NAV_INDICATOR     = "nav_indicator";    //导航指示信息NAV_INDICATOR
        public static  final String  ADJUST_LIGHT      = "adjust_light";     //亮度调节
        public static  final String  AUTO_ADJUST_LIGHT = "auto_adjust_light";//是否自动调节
        public static  final String  ADJUST_MOTOR      = "adjust_motor";     //调节马达
    }

    public void send2Hud(String action,Object settings){
        ProtoMsg protoMsg = new ProtoMsg(action, JSON.toJSONString(settings));
        ARHudComm.getInstance().sendToHud(protoMsg.toBytes());
    }
}
